import axios, {
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  AxiosError,
  InternalAxiosRequestConfig,
} from "axios";

import storage from "@/utils/storage";
interface AxiosRequestConfigFace extends AxiosRequestConfig {
  noToken?: boolean;
}
let isSx = false;
const service = axios.create({
  baseURL: "/spi", // url = base url + request url
  // withCredentials: true, //
  timeout: 25000, // 超时实际
});
// 是否正在刷新
let isRefreshing = false;
// 存储请求的数组
let cacheRequestArr: Function[] = [];
// 无法换到token后的过期方法
const loginOut = () => {
  storage.remove("chattoken");
};
// 换完token后，把并发的请求 继续开始
const afreshRequest = (token: string) => {
  cacheRequestArr.map((cb) => cb(token));
  cacheRequestArr = [];
  isSx = true;
};
const refreshRequest = (config: AxiosRequestConfigFace) => {
  let retry = new Promise((resolve) => {
    cacheRequestArr.push((token: string) => {
      config!.headers!["Authorization"] = "Bearer " + token;
      // 将请求挂起
      resolve(config);
    });
  });
  return retry;
};
// 核心方法
const refreshToken = (config: AxiosRequestConfigFace) => {
  if (isRefreshing) {
    return refreshRequest(config);
  } else {
    console.log("开始刷新token");
    isRefreshing = true;
    // 刷新token的方法，自己整下吧，我的是放pinia 里面，顺便调用完把token之类的换了
    loginChat()
      .then((res) => {
        const token = res.data.token;
        storage.set("chattoken", token);
        afreshRequest(token!);
      })
      .catch(() => {
        //  ElMessage.error("登录过期");
        loginOut();
      })
      .finally(() => {
        isRefreshing = false;
      });
    // 把当前请求也加入进去
    return refreshRequest(config);
  }
};

service.interceptors.request.use(
  (config: any) => {
    console.log("发送请求");
    console.log(config);

    const token: any = storage.get("chattoken", false);
    if (token) {
      config!.headers!["Authorization"] = "Bearer " + token;
    } else if (!config.header?.noToken) {
      return refreshToken(config);
    }
    console.log("发送请求");

    console.log(config);
    return config;
  },
  (error: AxiosError) => {
    console.log(error);
    return Promise.reject(error);
  }
);

service.interceptors.response.use(
  async (response: AxiosResponse<any>) => {
    console.log(response);
    const res = response.data;
    if (res.code === 200) {
      return res;
    } else {
      if (res.code === 401) {
        console.log("401");
        loginOut();
        return;
      } else {
      }
      return Promise.reject(res);
    }
  },
  (error) => {
    return Promise.reject(error);
  }
);

export function loginChat() {
  return service({
    url: "/api/v1/bind-mobile",
    method: "post",
    data: {
      phone: "13548585135",
      code: "999999",
    },
    headers: { noToken: true },
  });
}

interface NewChatFace {
  dialogue_id: number;
  title: string;
}
export function newChat(): Promise<IResponse<NewChatFace>> {
  return service({
    url: "/api/v1/new-dialogue",
    method: "post",
    baseURL: "/spi",
    data: {
      ins_id: 0,
    },
  });
}
declare interface ChatMessage {
  ask_demo?: string;
  created_at?: string;
  dialogue_id?: number;
  id: number;
  last_id?: number;
  rest_count?: number;
  role?: string;
  status?: number;
  text: string;
  updated_at?: string;
  user_id?: number;
}
export function sendChat(msg: string): Promise<IResponse<ChatMessage>> {
  const chatId = storage.get("chatId", false);
  return service({
    url: `/api/v1/dialogue/${chatId}/send`,
    method: "POST",
    baseURL: "/spi",
    headers: {
      "content-type": "application/x-www-form-urlencoded",
      accept: "application/json",
    },
    data: {
      message: msg,
    },
  });
}
